package com.ruoyi.mdm.service.impl;

import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.mdm.domain.SpuInfoEntity;
import com.ruoyi.mdm.repository.SpuInfoRepository;
import com.ruoyi.mdm.service.ISpuInfoService;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.client.erhlc.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.client.erhlc.NativeSearchQuery;
import org.springframework.data.elasticsearch.client.erhlc.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.stereotype.Service;

import jakarta.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;

@Service
public class SpuInfoServiceImpl implements ISpuInfoService {

    @Resource
    private ElasticsearchRestTemplate elasticsearchRestTemplate;

    @Resource
    private SpuInfoRepository spuInfoRepository;

    @Override
    public SearchHits<SpuInfoEntity> searchSpuInfo(SpuInfoEntity spuInfoEntity) {

        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        // 关键字模糊检索
        if (StringUtils.isNotEmpty(spuInfoEntity.getKeyword())) {
//            boolQueryBuilder.must(QueryBuilders.matchQuery("keyword", spuInfoEntity.getKeyword()));
            boolQueryBuilder.must(QueryBuilders.matchPhrasePrefixQuery("keyword", spuInfoEntity.getKeyword()));
//            boolQueryBuilder.must(QueryBuilders.multiMatchQuery(spuInfoEntity.getKeyword(),
//                    "spu_name", "spu_name_en", "spu_short_name", "spu_nick_name"));
        }

//        // 品牌编码
//        if (StringUtils.isNotEmpty(spuInfoEntity.getOwnerId())) {
//            boolQueryBuilder.must(QueryBuilders.termQuery("owner_id", spuInfoEntity.getOwnerId()));
//        }
        // 品牌编码 多个时候 或者
        if (StringUtils.isNotEmpty(spuInfoEntity.getOwnerId())) {
            List<String> ownerIdList = Arrays.asList(spuInfoEntity.getOwnerId().split(","));
            BoolQueryBuilder boolOwnerBuilder = QueryBuilders.boolQuery();
            for (String ownerId : ownerIdList) {
                boolOwnerBuilder.should(QueryBuilders.termQuery("owner_id", ownerId));
            }
            boolOwnerBuilder.minimumShouldMatch(1);

            boolQueryBuilder.must(boolOwnerBuilder);
        }

        // 条件+排序+分页
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();

        nativeSearchQueryBuilder.withQuery(boolQueryBuilder);
        // 命中得分排序
        if (StringUtils.isNotEmpty(spuInfoEntity.getKeyword())) {
            nativeSearchQueryBuilder.withSort(SortBuilders.scoreSort().order(SortOrder.DESC));
        }
        // 排序
        nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort("update_time.keyword").order(SortOrder.DESC));
        // 分页
        nativeSearchQueryBuilder.withPageable(PageRequest.of(spuInfoEntity.getPage(), spuInfoEntity.getSize()));

        NativeSearchQuery nativeSearchQuery = nativeSearchQueryBuilder.build();
        SearchHits<SpuInfoEntity> searchHits = elasticsearchRestTemplate.search(nativeSearchQuery, SpuInfoEntity.class);

        return searchHits;
    }

    @Override
    public SpuInfoEntity findById(Long id) {
        Optional<SpuInfoEntity> optionalSpuInfoEntity = spuInfoRepository.findById(id);
        return optionalSpuInfoEntity.get();
    }

    @Override
    public int add(SpuInfoEntity spuInfoEntity) {
        spuInfoRepository.save(spuInfoEntity);
        return 1;
    }

    @Override
    public int addAll(List<SpuInfoEntity> spuInfoEntityList) {
        spuInfoRepository.saveAll(spuInfoEntityList);
        return 1;
    }

    @Override
    public int delete(Long id) {
        spuInfoRepository.deleteById(id);
        return 1;
    }

    @Override
    public int deleteAll() {
        spuInfoRepository.deleteAll();
        return 1;
    }
}
